#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#  Copyright (C) 2020 ShenZhen Powersmart Information Technology Co.,Ltd
#  All Rights Reserved.
#  本软件为深圳博沃智慧开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、
#  复制、修改或发布本软件.

# @Time : 2025/9/10 09:21
# @File : location_service.py
# @Project: 
# @Author : wanghongtao
# @Software: PyCharm

import json
import requests
import time
from typing import Dict, Optional, Tuple, Any
from dataclasses import dataclass

from services.ai_service_factory import AIService, ServiceConfig, ServiceRequest, ServiceResponse, ServiceType, \
    ServiceStatus
from core.config import settings
from core.logging_config import get_logger

# 配置日志
logger = get_logger("location_service")


@dataclass
class LocationResult:
    """地理位置结果"""
    address: str
    longitude: Optional[float] = None
    latitude: Optional[float] = None
    confidence: float = 0.0
    error_message: Optional[str] = None

location_analysis_config = ServiceConfig(
    service_type=ServiceType.LOCATION_ANALYSIS,
    name="地理信息识别",
    description="经纬度识别",
    version="v1.0",
    enabled=True,
    max_concurrent_requests=10,
    timeout=30,
    retry_count=3,
    model_config={},
    api_config={}
)

class LocationAnalysisService(AIService):
    """地理位置分析服务"""
    
    def __init__(self, config: ServiceConfig=location_analysis_config):
        super().__init__(config)
        self.api_key = settings.tianditu_api_key
        self.base_url = "http://api.tianditu.gov.cn/geocoder"
        self.session = None
        
    async def initialize(self) -> bool:
        """初始化服务"""
        try:
            # 创建HTTP会话
            self.session = requests.Session()
            self.session.timeout = 10
            
            # 验证API密钥
            if not self.api_key:
                logger.warning("天地图API密钥未配置，服务将使用模拟模式")
            else:
                # 测试API连接
                test_result = await self._test_api_connection()
                if not test_result:
                    logger.warning("天地图API连接测试失败，服务将使用模拟模式")
            
            logger.info("地理位置分析服务初始化成功")
            self.status = ServiceStatus.READY
            return True
            
        except Exception as e:
            logger.error(f"地理位置分析服务初始化失败: {str(e)}")
            return False
    
    async def _test_api_connection(self) -> bool:
        """测试API连接"""
        try:
            test_address = "北京市朝阳区"
            params = {
                "ds": json.dumps({"keyWord": test_address}),
                "tk": self.api_key
            }
            
            response = self.session.get(self.base_url, params=params)
            if response.status_code == 200:
                result = response.json()
                return result.get("status") == "0"
            
        except Exception as e:
            logger.error(f"API连接测试失败: {str(e)}")
        
        return False
    
    async def process(self, request: ServiceRequest) -> ServiceResponse:
        """处理地理位置分析请求"""
        start_time = time.time()
        
        try:
            address = request.data.get("address", "")
            if not address:
                return ServiceResponse(
                    request_id=request.request_id,
                    service_type=request.service_type,
                    success=False,
                    error_message="地址内容不能为空"
                )
            
            # 执行地址解析
            location_result = await self._analyze_location(address)
            
            return ServiceResponse(
                request_id=request.request_id,
                service_type=request.service_type,
                success=True,
                data={
                    "location_result": location_result.__dict__,
                    "processing_details": {
                        "address_length": len(address),
                        "api_used": "tianditu" if self.api_key else "simulation",
                        "geocoding_method": "api_geocoding"
                    }
                },
                processing_time=time.time() - start_time
            )
            
        except Exception as e:
            logger.error(f"地理位置分析失败: {str(e)}")
            return ServiceResponse(
                request_id=request.request_id,
                service_type=request.service_type,
                success=False,
                error_message=str(e),
                processing_time=time.time() - start_time
            )
    
    async def _analyze_location(self, address: str) -> LocationResult:
        """分析地理位置信息"""
        result = LocationResult(address=address)
        
        if self.api_key:
            # 使用天地图API进行地理编码
            coordinates = await self._address_to_coordinates(address)
            if coordinates:
                result.longitude, result.latitude = coordinates
                result.confidence = 0.9

            else:
                result.confidence = 0.1
                result.error_message = "地理编码失败"
        else:
            result.error_message = "天地图API密钥未配置"
        return result
    
    async def _address_to_coordinates(self, address: str) -> Optional[Tuple[float, float]]:
        """将地址转换为经纬度坐标"""
        if not address:
            logger.error("地址不能为空")
            return None
            
        try:
            # 构建请求参数
            params = {
                "ds": json.dumps({"keyWord": address}),
                "tk": self.api_key
            }
            
            # 发送请求
            logger.info(f"正在查询地址: {address}")
            response = self.session.get(self.base_url, params=params)
            
            # 检查响应状态
            if response.status_code != 200:
                logger.error(f"请求失败，状态码: {response.status_code}")
                return None
                
            # 解析响应结果
            result = response.json()
            
            # 检查返回状态
            if result.get("status") != "0":
                logger.error(f"API返回错误状态: {result.get('status')}, 消息: {result.get('msg')}")
                return None
                
            # 提取经纬度
            location = result.get("location")
            if not location:
                logger.error("未找到地址对应的经纬度信息")
                return None
                
            lon = float(location.get("lon", 0))
            lat = float(location.get("lat", 0))
            
            # 验证经纬度有效性
            if lon == 0 and lat == 0:
                logger.error(f"返回的经纬度无效: lon={lon}, lat={lat}")
                return None
                
            logger.info(f"地址 {address} 转换成功: lon={lon}, lat={lat}")
            return lon, lat
            
        except json.JSONDecodeError as e:
            logger.error(f"JSON解析错误: {str(e)}")
        except requests.RequestException as e:
            logger.error(f"网络请求异常: {str(e)}")
        except Exception as e:
            logger.error(f"地址转经纬度发生未知错误: {str(e)}")
            
        return None

    async def health_check(self) -> Dict[str, Any]:
        """健康检查"""
        api_status = "available" if self.api_key else "simulation_mode"
        
        if self.api_key:
            # 测试API连接
            try:
                test_result = await self._test_api_connection()
                api_status = "healthy" if test_result else "degraded"
            except Exception:
                api_status = "error"
        
        return {
            "healthy": api_status in ["available", "healthy"],
            "service_type": "location_analysis",
            "api_status": api_status,
            "capabilities": {
                "geocoding": True,
                "reverse_geocoding": False,
                "batch_processing": True,
                "max_batch_size": 100,
                "supported_regions": ["中国大陆"]
            },
            "configuration": {
                "has_api_key": bool(self.api_key),
                "api_endpoint": self.base_url if self.api_key else None
            }
        }
    
    def get_capabilities(self) -> Dict[str, Any]:
        """获取服务能力"""
        return {
            "description": "将地址转换为经纬度坐标，提供地理位置分析服务",
            "input_format": {"address": "string"},
            "output_format": {
                "location_result": "object",
                "processing_details": "object"
            },
            "supported_features": [
                "address_geocoding",
                "coordinate_extraction",
                "region_analysis",
                "confidence_scoring"
            ],
            "limitations": [
                "仅支持中国大陆地区地址",
                "需要天地图API密钥以获得最佳效果",
                "无API密钥时使用模拟模式"
            ]
        }
    
    async def batch_process(self, addresses: list) -> list:
        """批量处理地址"""
        results = []
        
        for address in addresses:
            try:
                result = await self._analyze_location(address)
                results.append(result.__dict__)
            except Exception as e:
                logger.error(f"批量处理地址失败: {address}, 错误: {str(e)}")
                error_result = LocationResult(
                    address=address,
                    error_message=str(e)
                )
                results.append(error_result.__dict__)
        
        return results


